package com.ygqh.baby.service.impl;

import com.ygqh.baby.ao.QueryInfo;
import com.ygqh.baby.ao.ResultSet;
import com.ygqh.baby.ao.TaskMethod;
import com.ygqh.baby.mapper.YgTaskTimeMapper;
import com.ygqh.baby.po.YgTaskTime;
import com.ygqh.baby.po.YgTaskTimeExample;
import com.ygqh.baby.service.YgTaskTimeService;
import com.ygqh.baby.service.YgTaskTimeTemplate;
import com.ygqh.baby.service.wdtqyb.exception.WdtException;
import com.ygqh.baby.utils.DateConvertUtils;
import com.ygqh.baby.utils.ExceptionUtil;
import com.ygqh.baby.utils.MailUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * @author admin
 */
@Service
public class YgTaskTimeServiceImpl implements YgTaskTimeService {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private YgTaskTimeMapper ygTaskTimeMapper;
    @Autowired
    private MailUtil mailUtil;

    @Override
    public List<YgTaskTime> find() {
        YgTaskTimeExample example = new YgTaskTimeExample();
        example.createCriteria();
        return ygTaskTimeMapper.selectByExample(example);
    }

    @Override
    public List<YgTaskTime> findByName(String methodName) {
        YgTaskTimeExample example = new YgTaskTimeExample();
        example.createCriteria().andMothodNameEqualTo(methodName);
        return ygTaskTimeMapper.selectByExample(example);
    }

    @Override
    public int findCount() {
        YgTaskTimeExample example = new YgTaskTimeExample();
        example.createCriteria();
        return ygTaskTimeMapper.countByExample(example);
    }

    @Override
    public YgTaskTime findById(Long id) {
        return ygTaskTimeMapper.selectByPrimaryKey(id);
    }

    @Override
    public int save(YgTaskTime ygTaskTime) {
        return ygTaskTimeMapper.insertSelective(ygTaskTime);
    }

    @Override
    public int update(YgTaskTime ygTaskTime) {
        return ygTaskTimeMapper.updateByPrimaryKeySelective(ygTaskTime);
    }

    @Override
    public ResultSet<YgTaskTime> search(QueryInfo queryInfo, String q) {
        List<YgTaskTime> list = ygTaskTimeMapper.selectSuper(queryInfo, q);
        int count = ygTaskTimeMapper.countSuper(q);
        ResultSet<YgTaskTime> resultSet = new ResultSet<YgTaskTime>(count, list);
        return resultSet;
    }

    @Override
    public int saveOrUpdate(YgTaskTime ygTaskTime) {
        int r = 0;
        if (ygTaskTime.getId() != null) {
            r = this.update(ygTaskTime);
        } else {
            r = this.save(ygTaskTime);
        }
        return r;
    }

    @Override
    public YgTaskTime findLastByTaskMethod(TaskMethod method) {
        YgTaskTimeExample example = new YgTaskTimeExample();
        example.createCriteria().andMothodNameEqualTo(method.name());
        example.setOrderByClause("id desc");
        List<YgTaskTime> list = ygTaskTimeMapper.selectByExample(example);
        if (list != null && list.size() > 0) {
            return list.get(0);

        }
        return null;
    }

    @Override
    public int updateTaskTime(Long id, TaskMethod method, Date currentTime, String remark) {
        YgTaskTime task = new YgTaskTime();
        task.setId(id);
        task.setMothodName(method.name());
        task.setRunTime(currentTime);
        task.setRemark(remark);

        return this.update(task);
    }

    @Override
    public int saveOrUpdate(String methodName, Date date, String remark) {
        YgTaskTimeExample example = new YgTaskTimeExample();
        example.createCriteria().andMothodNameEqualTo(methodName);
        List<YgTaskTime> taskTimes = ygTaskTimeMapper.selectByExample(example);
        int r;
        if (taskTimes.isEmpty()) {
            YgTaskTime taskTime = new YgTaskTime();
            taskTime.setMothodName(methodName);
            taskTime.setRunTime(new Date());
            taskTime.setRemark(remark);
            r = ygTaskTimeMapper.insertSelective(taskTime);
        } else {
            YgTaskTime taskTime = taskTimes.get(0);
            taskTime.setRunTime(date);
            taskTime.setRemark(remark);
            r = ygTaskTimeMapper.updateByPrimaryKeySelective(taskTime);
        }
        return r;
    }

    @Override
    public void autoExecute(String methodName, YgTaskTimeTemplate template) {

        List<YgTaskTime> taskTimes = this.findByName(methodName);
        Date currentDate = new Date();
        currentDate = DateConvertUtils.formatToDate(currentDate, "yyyy-MM-dd");
        Date recordDate;
        if (taskTimes.isEmpty()) {
            recordDate = DateConvertUtils.addDay(currentDate, 0 - 1);
        } else {
            recordDate = taskTimes.get(0).getRunTime();
            recordDate = DateConvertUtils.formatToDate(recordDate, "yyyy-MM-dd");
        }
        Long interval = DateConvertUtils.diffDayes(recordDate, currentDate);
        Date temp = currentDate;
        for (int i = 0, k = 1; i < interval; i++) {
            String tempStr = DateConvertUtils.format(temp);
            try {
                template.execute(DateConvertUtils.parse(tempStr, "yyyy-MM-dd"));
                this.saveOrUpdate(methodName, new Date(), "正常");
            } catch (Exception e) {
                e.printStackTrace();
                break;
            }
            temp = DateConvertUtils.addDay(temp, 0 - k);
        }
    }

    @Override
    public void execute(TaskMethod methodName, int timeInterval, YgTaskTimeTemplate template) {
        Date lastRunTime = new Date();
        Date runTime;

        long diff = 0L;
        YgTaskTime taskTime = this.findLastByTaskMethod(methodName);
        if (taskTime != null) {
            // 获取最后一次执行时间与当前时间的间隔几天
            if (methodName.getIntervalType().equals("day")) {

                diff = DateConvertUtils.diffDayes(taskTime.getRunTime(), lastRunTime);
                diff = diff / timeInterval;
            } else {
                diff = DateConvertUtils.diffMinutes(taskTime.getRunTime(), lastRunTime);
                diff = diff / timeInterval;
            }
            lastRunTime = taskTime.getRunTime();
        }
        for (int i = 0; i < diff; i++) {
            lastRunTime.setSeconds(0);
            if (methodName.getIntervalType().equals("day")) {
                runTime = DateConvertUtils.addDay(lastRunTime, (i + 1) * timeInterval);
            } else {
                runTime = DateConvertUtils.addMinute(lastRunTime, (i + 1) * timeInterval);
            }
            try {
                template.execute(runTime);
                this.saveOrUpdate(methodName.name(), runTime, "执行成功; " + DateConvertUtils.formatDateTime(new Date()));
            } catch (Exception e) {
                this.saveOrUpdate(methodName.name(), null, ExceptionUtil.getExceptionMsg(e));
                e.printStackTrace();
                logger.error("{} ->任务执行失败 --> \r\n{}", methodName.name(), e);
                if (e instanceof WdtException) {
                    mailUtil.simpleSend("sunshuo@yiigoo.com",
                            "【" + methodName + "任务】执行失败", ExceptionUtil.getExceptionMsg(e));
                }
                break;
            }
        }
    }
}
